# -*- coding: UTF-8 -*-
#! /usr/bin/env python
# Copyright (C) 2018 Nokia. All rights reserved.

import re
import os
import math
import sys

File_Name = 'combine_beam' #只有包含这个名称的文件能够被解析
Out_Write_File_Name = 'beaminit.sh'
First_line_Cmd = 'devmem 0xa0001220 32 0x1'
Last_line_Cmd = 'devmem 0xa0001220 32 0x0'
REGX_GETVALUE = "([-|+]?\d+.\d+(?:e-\d+)?|0)([-|+].*?)i"
REGX_GETBEAMID = "beam_id\s*=\s*(\d+)"

class RFParse():
    def __init__(self, file_name):
        self.file = file_name
        self.file_size = os.path.getsize(self.file)
        self.file_obj = open(self.file)
        self.fileData = self.file_obj.read()
        self.beamindex = 0
        self.value = ()
    
    # 正则获取beamid的值
    def getBeamID(self):
        RegexGetBeamId = re.compile(REGX_GETBEAMID)
        if(RegexGetBeamId.search(self.fileData) == None):
            raise Exception("can't find beam index")
        else:
            self.beamindex = RegexGetBeamId.search(self.fileData).group(1)
        
    # 正则获取参数的值,虚部实部
    def getParamValue(self):
        RegexGetValue = re.compile(REGX_GETVALUE)
        self.value = RegexGetValue.findall(self.fileData)
        print self.value
        if(self.value == []):
            raise Exception("value is null or can't find value")

    def valueToHex(self):
        Hex_list = []
        for item in self.value:
            data_hex = []
            real_dec = float(item[0])
            img_dec = float(item[1])
            # 对虚数值进行判断，+-0.0001都视为0
            if(img_dec < 0.0001 and img_dec > -0.0001):
                img_dec = 0
            # 将数据转换为16进制
            data_hex.append(RFParse.Hex2Bin(real_dec))
            data_hex.append(RFParse.Hex2Bin(img_dec))
            Hex_list.append(data_hex)
        return Hex_list
        
    def LinkCmd(self, data_list):
        data_total = []
        data_total.append(First_line_Cmd) # 头加一个指令
        for i,dataItem in enumerate(data_list):
            data = 'devmem 0xa04' + RFParse.checkLen(hex(int(self.beamindex)*128 + i*4).replace('0x','').upper(),5) + ' 32 0x' + str(dataItem[1]) + str(dataItem[0])
            data_total.append(data)
        data_total.append(Last_line_Cmd) #末尾加一个指令
        print ('---------cmd create success---------')
        return data_total
        
    @staticmethod   
    def OutWriteToSh(All_data_list):
        print ('---------start to write to--------',Out_Write_File_Name)
        write_file_object = open(Out_Write_File_Name, 'w')
        sortedndex = sorted(All_data_list) #对beamindex进行排序
        try:
            for index in sortedndex:
                write_file_object.writelines('# beam_index = '+str(index)+'\n')
                for index_data in All_data_list[index]:
                    write_file_object.writelines(index_data+'\n')
                write_file_object.writelines('\n') #空一行好看
        finally:
            write_file_object.close( )
            print ('write finish')

    @staticmethod       
    def Hex2Bin(num):
        if(num < 1 and num > -1):
            if(num > 0):
                hexNum = hex(int(math.pow(2, 15)*num)).replace('0x','').upper()
                return RFParse.checkLen(hexNum,4)
            else:
                if(num < 0):
                    return RFParse.checkLen(hex(int(RFParse.ReverseBin(bin(-1 + -int(math.pow(2, 15)*num))),2)).replace('0x','').upper(),4)
                else:
                    return '0000'
        else:
            if(num >= 1):
                return hex(int(math.pow(2, 15)-1)).replace('0x','').upper()
            else:
                return hex(int(math.pow(2, 16)-1)).replace('0x','').upper()

    @staticmethod       
    def checkLen(hexnum,count):
         while(len(hexnum) != count):
            hexnum = '0' + hexnum
         return hexnum
    
    @staticmethod
    def ReverseBin(strBin):
        strBin = strBin.replace('b','')
        zeroadd = 16 - len(strBin)
        strBin = '0'*zeroadd + strBin
        reverBin = ''
        for one in strBin:
            if one == '0':
                reverBin += '1'
            else:
                reverBin += '0'
        return reverBin
        
def findAllfile():
    file_list = os.listdir('./') #列出目录下的所有文件和目录
    file_need_parse = []         #检索需要解析的文件
    for file in file_list:
        if File_Name in file:
            file_need_parse.append(file)
    return file_need_parse
    
if __name__ == "__main__":
    # parsefiles = findAllfile()
    # print (parsefiles)
    # All_data_list = {}
    # try:
        # for file in parsefiles:
            # print ('-----------start parse------------',file)
            # rfparse = RFParse(file)
            # rfparse.getBeamID()
            # rfparse.getParamValue()
            # All_data_list[rfparse.beamindex] = rfparse.LinkCmd(rfparse.valueToHex())
    # except (Exception,e):
        # print (e.message)
        # exit()
    #RFParse.OutWriteToSh(All_data_list)
    rfparse = RFParse(sys.argv[1])
    try:
        rfparse.getParamValue()
    except Exception,e:
        print e.message